
--[[
    通用工具类
]]

local uu = {}

--输出日志--
function uu.log(str)
	log(str)
end

--错误日志--
function uu.logError(str)
	logError(str)
end

--警告日志--
function uu.logWarn(str)
	logWarn(str)
end

function uu.initEnumTable( enumTable )
	local t = {}
	for name, id in pairs(enumTable) do
		t[id] = name
	end
	for id, name in pairs(t) do
		enumTable[id] = name
	end
end

function uu.MakeFunc( func, ... )
	local args = {...}
	return function()
		if func then
			func(unpack(args))
		end
	end
end

function uu.SafeCallFunc( func, ... )
	if func then
		local ret, err = pcall(func, ...)
		if not ret then
			if Util.hasLog then Util.LogError(err) end
		end
		return true
	end
	return false
end

function uu.SafeDoFunc( func, ... )
	if func then
		local result = {}
		local ret, err = pcall(function(...)
			result = {func(...)}
		end, ...)
		if ret then
			return unpack(result)
		end
		if Util.hasLog then Util.LogError(err) end
	end
end

function DelayRun( second, func, ... )
	local args = {...}
	return coroutine.start(function()
		if second ~= nil then
			coroutine.wait(second)
		end
		func(unpack(args))
	end);
end

function uu.CancelDelayRun( co )
	if co then
		if co ~= coroutine.running() then
			coroutine.stop(co)
		else
			DelayRun(nil, coroutine.stop, co)
		end
	end
end

function uu.StartTimer( delay, func, times, forever )
	return coroutine.start(function()
		times = times or 1
		repeat
			coroutine.wait(delay);
			uu.SafeCallFunc(func)
			times = times - 1
		until(times == 0 or forever == false)
	end)
end

function uu.StopTimer(timer)
	uu.CancelDelayRun(timer)
end

function uu.PrintTable(tab)
	local str = {}

	local function internal(tab, str, indent)
		for k,v in pairs(tab) do
			if type(v) == "table" then
				table.insert(str, indent..tostring(k)..":\n")
				internal(v, str, indent..' ')
			else
				table.insert(str, indent..tostring(k)..": "..tostring(v).."\n")
			end
		end
	end

	internal(tab, str, '')
	return table.concat(str, ' ')
end

function uu.PrintTable2( tbl , level, filteDefault)
	local msg = ""
	filteDefault = filteDefault or true --默认过滤关键字（DeleteMe, _class_type）
	level = level or 1
	local indent_str = ""
	for i = 1, level do
		indent_str = indent_str.."  "
	end

	print(indent_str .. "{")
	for k,v in pairs(tbl) do
		if filteDefault then
			if k ~= "_class_type" and k ~= "DeleteMe" then
				local item_str = string.format("%s%s = %s", indent_str .. " ",tostring(k), tostring(v))
				print(item_str)
				if type(v) == "table" then
					uu.PrintTable(v, level + 1)
				end
			end
		else
			local item_str = string.format("%s%s = %s", indent_str .. " ",tostring(k), tostring(v))
			print(item_str)
			if type(v) == "table" then
				uu.PrintTable(v, level + 1)
			end
		end
	end
	print(indent_str .. "}")
end

function uu.PrintLuaTable (lua_table)
	log(uu.Dump(lua_table))
end

function uu.isString( value )
	return type(value) == "string"
end

function uu.isNumber( value )
	return type(value) == "number"
end

function uu.isFunction( value )
	return type(value) == "function"
end

function uu.isTable( value )
	return type(value) == "table"
end

function uu.MoneyFormat( money )
	money = tostring(money)
	local cnt = #money - 4
	local ret = ""
	while cnt > 0 do
		ret = ","..string.sub(money, -4)..ret
		money = string.sub(money, 1, -5)
		cnt = cnt - 4
	end
	return money..ret
end

function uu.IsNil(uobj)
	return uobj == nil or uobj:Equals(nil)
end

function uu.CheckChinese(word)
	local str = word
	if #str >0 and #str /3 %1 == 0 then
		for i=1,#str,3 do
			local temp = string.byte(str,i)
			if temp >= 240 or temp < 224 then
				return false
			end
		end
		-- 228 184 128--233 191 191
		for i=1,#str,3 do
			local temp1 = string.byte(str,i)
			local temp2 = string.byte(str,i+1)
			local temp3 = string.byte(str,i+2)
			if temp1 <228 or temp1 >233 then
				return false
			elseif temp1 == 228 then
				if temp2 < 184 then
					return false
				elseif temp2 == 184 then
					if temp3 <128 then
						return false
					end
				end
			elseif temp1 == 233 then
				if temp2 >191 then
					return false
				elseif temp2 == 191 then
					if temp3 >191 then
						return false
					end
				end
			end
		end
		return true
	end
end

--过长就变成：亲朋用户...
function uu.GetShortName(sName,nMaxCount,nShowCount)
	if sName == nil or nMaxCount == nil then
		return
	end
	local sStr = sName
	local tCode = {}
	local tName = {}
	local nLenInByte = #sStr
	local nWidth = 0
	if nShowCount == nil then
		nShowCount = nMaxCount - 3
	end
	for i=1,nLenInByte do
		local curByte = string.byte(sStr, i)
		local byteCount = 0;
		if curByte>0 and curByte<=127 then
			byteCount = 1
		elseif curByte>=192 and curByte<223 then
			byteCount = 2
		elseif curByte>=224 and curByte<239 then
			byteCount = 3
		elseif curByte>=240 and curByte<=247 then
			byteCount = 4
		end
		local char = nil
		if byteCount > 0 then
			char = string.sub(sStr, i, i+byteCount-1)
			i = i + byteCount -1
		end
		if byteCount == 1 then
			nWidth = nWidth + 1
			table.insert(tName,char)
			table.insert(tCode,1)

		elseif byteCount > 1 then
			nWidth = nWidth + 2
			table.insert(tName,char)
			table.insert(tCode,2)
		end
	end

	if nWidth > nMaxCount then
		local _sN = ""
		local _len = 0
		for i=1,#tName do
			_sN = _sN .. tName[i]
			_len = _len + tCode[i]
			if _len >= nShowCount then
				break
			end
		end
		sName = _sN .. "..."
	end
	return sName
end

--ticket转换成： 00:00:00这种格式
function uu.TicketFormat(nTicket)
	local nHour = math.modf(nTicket / 3600);
	local nMin = math.modf((nTicket - nHour * 3600) / 60);
	local nSec = nTicket % 60;
	local szHourText = tostring(nHour);
	local szMinText = tostring(nMin);
	local szSecText = tostring(nSec);
	if (nHour < 10) then
		szHourText = "0" .. szHourText;
	end
	if (nMin < 10) then
		szMinText = "0" .. szMinText;
	end
	if (nSec < 10) then
		szSecText = "0" .. szSecText;
	end
	return szHourText..":"..szMinText..":"..szSecText;
end

function uu.FormatMoneyWan(nMoneyNum)
	if nMoneyNum == nil or tonumber(nMoneyNum) == 0 then
		return "0"
	end
	nMoneyNum = tonumber(nMoneyNum)
	local WAN = 10000
	local strMoneyNum = "";
	if nMoneyNum >= WAN then
		strMoneyNum = string.format("%.0f", nMoneyNum / WAN)
		strMoneyNum = strMoneyNum .."万"
	else
		strMoneyNum = tostring(nMoneyNum)
	end
	return strMoneyNum
end

function uu.CheckPostObjStatus(trans)
	local ret,msg = pcall(function()
		local value = Util.UObjectDestroyed(trans)
		if value == true then
			return {result = true}
		else
			return {result = false}
		end
	end)
	if ret == false then
		return true
	else
		return msg.result
	end
end

function uu.date2time(date)
	--data = "2017-06-22 17:27:20"
	--如果日期小于"1970-01-01 00:08:00"（东八区0点），则返回nil值
	local Y = string.sub(date, 1, 4)
	local M = string.sub(date, 6, 7)
	local D = string.sub(date, 9, 10)
	local h = string.sub(date, 12, 13)
	local m = string.sub(date, 15, 16)
	local s = string.sub(date, 18, 19)
	return os.time({year=Y, month=M, day=D, hour=h, min=m, sec=s})
end

function uu.now()
	return os.date("%Y-%m-%d %X")
end

--获取一个lua table 所有key值，无论数字还是字母
function uu.GetTableKeys(tab)
	local ret = {}
	for i,v in pairs(tab) do
		table.insert(ret,i)
	end
	table.sort(ret,function(a,b) return a<b end)
	return ret
end

--把秒转换成
function uu.SecondsTimeToStr(sec)
	-- body
	local hours = math.floor(sec / 3600)
	local left = sec - 3600 * hours
	local mins = math.floor(left / 60)
	local left = left - 60 * mins
	local secs = left
	local hours_str = hours > 0 and "" .. hours .. "小时" or ""
	local mins_str = mins > 0 and "" .. mins .. "分钟" or ""
	local secs_str = secs > 0 and "" .. secs .. "秒" or ""
	return "" .. hours_str .. mins_str .. secs_str
end

-- 判断utf8字符byte长度
-- 0xxxxxxx - 1 byte
-- 110yxxxx - 192, 2 byte
-- 1110yyyy - 225, 3 byte
-- 11110zzz - 240, 4 byte
function uu.chsize(char)
	if not char then
		print("not char")
		return 0
	elseif char > 240 then
		return 4
	elseif char > 225 then
		return 3
	elseif char > 192 then
		return 2
	else
		return 1
	end
end

-- 计算utf8字符串字符数, 各种字符都按一个字符计算
-- 例如uu.utf8len("1你好") => 3
function uu.utf8len(str)
	local len = 0
	local currentIndex = 1
	while currentIndex <= #str do
		local char = string.byte(str, currentIndex)
		currentIndex = currentIndex + uu.chsize(char)
		len = len +1
	end
	return len
end

-- 截取utf8 字符串
-- str:         要截取的字符串
-- startChar:   开始字符下标,从1开始
-- numChars:    要截取的字符长度
function uu.utf8sub(str, startChar, numChars)
	local startIndex = 1
	while startChar > 1 do
		local char = string.byte(str, startIndex)
		startIndex = startIndex + uu.chsize(char)
		startChar = startChar - 1
	end

	local currentIndex = startIndex

	while numChars > 0 and currentIndex <= #str do
		local char = string.byte(str, currentIndex)
		currentIndex = currentIndex + uu.chsize(char)
		numChars = numChars -1
	end
	return str:sub(startIndex, currentIndex - 1)
end

-- 截取utf8 字符串名字，与uu.utf8sub不同，如果字符超出个数，后面加...
function uu.utf8NameSub(str,startIndex,numChars)
	if uu.utf8len(str) > numChars then
		return uu.utf8sub(str,startIndex,numChars - 1) .. "..."
	else
		return uu.utf8sub(str,startIndex,numChars)
	end
end

--把这样的数字1234567转换成这样的字符串1,234,567
function uu.numberToStrWithComma(num)
	local strNum = tostring(num)
	local lenStr = string.len(strNum)
	local ret = ""
	for i = 1 , math.ceil(lenStr/3) do
		local startIdx = lenStr - 3 * i + 1
		local endIdx = lenStr - 3 * (i - 1)
		if startIdx < 1 then startIdx = 1 end
		if i == 1 then
			ret = string.sub(strNum,startIdx,endIdx) .. ret
		else
			ret = string.sub(strNum,startIdx,endIdx) .. "," .. ret
		end
	end
	return ret
end

--用于把AssetsList.ini里面的字符串末尾换行符全部换成'\r\n'形式
function uu.addEnterAscii(str)
	local str1 = string.gsub(str,'\r\n','\n')
	local str2 = string.gsub(str1,'\r','\n')
	local ret = string.gsub(str2,'\n','\r\n')
	return ret
end

--手机号码加密，例如17712345678显示成177XXXXX678
function uu.phoneNumberToSecret(str)
	local len = string.len(tostring(str))
	local ret = ""
	for i = 1,len do
		if i > 3 and i < 9 then
			ret = ret .. "*"
		else
			ret = ret .. string.sub(str,i,i)
		end
	end
	return ret
end

function uu.merge(dst, src)
	table.foreach(src,
			function(i,v)
				dst[i] = v
			end
	)
end

function uu.StringFromat( srcStr,replacestr,...)
	local arg = {...}
	for i=1,#arg do
		srcStr = string.gsub(srcStr,replacestr,arg[i],1)
	end
	return srcStr
end

function uu.StringLen(str)
	local curIndex = 0
	local lastCount = 1
	local i = 1
	repeat
		lastCount = uu.StringByteCount(str, i)
		i = i + lastCount
		curIndex = curIndex + 1
	until(lastCount == 0)
	return curIndex - 1
end

--返回当前字符实际占用的字符数
function uu.StringByteCount(str, index)
	local curByte = string.byte(str, index)
	local byteCount = 1
	if curByte == nil then
		byteCount = 0
	elseif curByte > 0 and curByte <= 127 then
		byteCount = 1
	elseif curByte >= 192 and curByte < 223 then
		byteCount = 2
	elseif curByte >= 224 and curByte <239 then
		byteCount = 3
	elseif curByte >= 240 and curByte <= 247 then
		byteCount = 4
	end
	return byteCount
end

function uu.StringLastFind(str, pattern)
	-- 反向搜索:xxxxxxixx i的位置

	--1、先把str反转
	--2、从头开始查找i的位置(index)
	--3、str的长度 - index + 1 = i反向搜索的位置
	local rev = string.reverse(str)
	--local key = string.reverse(pattern)
	local pos = string.find(rev, pattern)
	if not pos then
		return nil
	end
	local _i = string.len(str) - pos + 1
	return _i
end

--数值格式化
function uu.NumberFormat(number,numlen)
	if not number then
		return "未刷新"
	end
	if (number < 10000) then
		return tostring(number)
	elseif (number < 100000000) then
		return uu.MergeNumber(number, 10000, numlen).."万"
	elseif (number < 999999999999) then
		return uu.MergeNumber(number, 100000000, numlen).."亿"
	else
		return "9999.9亿"
	end
end

--数值合并
function uu.MergeNumber(number, divNumber,numlen)
	local numberLength = 0    --数值最多显示6位
	if numlen ~= nil then
		numberLength = numlen
	elseif numlen == nil then
		numberLength = 6
	end
	local interger, decimal = math.modf(number/divNumber)
	local len = numberLength - #tostring(interger) + 1    --小数部分长度
	--取小数前len位的值
	local decimalFormat = string.format("%.10f", decimal)   --零界点会自动四舍五入 ，需要将小数点后延长几位
	decimal = tonumber(string.sub(tostring(decimalFormat), 1, len))
	--print("decimal format: "..decimalFormat)
	local total = interger
	if (decimal > 1e-5) then
		total = total + decimal     --确保小数结果最后一位不为0
	end

	local result = tostring(total)
	result = string.sub(result, 1, numberLength)
	return result
end

function uu.search(t, value)
	for k, v in pairs(t) do
		if v == value then
			return k
		end
	end
end

function uu.SafeRequire(path)
	--用该方法解决lua相互require
	local mdl = require(path)
	if type(mdl) == 'table' and mdl.InitRequire then
		mdl.InitRequire()
	end
	return mdl
end

function uu.ClassView(viewName,baseView,bundleName)
	--警告，改ClassView仅用于创建大厅界面类，游戏内的请自定义
	local CC = require("CC")
	baseView = baseView or CC.HallViewBase
	bundleName = bundleName or "prefab"
	local c = CC.class2(viewName,baseView)
	c.bundleName = bundleName
	c.viewName = viewName
	return c
end

function uu.CreateHallView( viewName, ... )
	local CC = require("CC")
	local obj = nil
	if uu.isString(viewName) then
		local viewClass = CC[viewName]
		if viewClass then
			obj = viewClass.new(...)
			obj:Create()
		else
			if Util.hasLog then
				Util.LogError('uu.CreateHallView '..viewName.." not find!")
			end
		end
	end
	return obj
end

--2018/9/21 0:00:00
function uu.SplitStr(str)
	local strArr = {}
	strArr=str:split(" ")
	local birth = {}
	local time = {}
	birth=strArr[1]:split("/")
	time=strArr[2]:split(":")
	return birth,time
end

--手机号码验证
function uu.checkPhone(sPhoneNum)
	local sFirstChar = string.sub(sPhoneNum,1,1)
	if tonumber(sPhoneNum) ~= nil and #sPhoneNum ==11 and sFirstChar =="1" then
		return true
	else
		return false
	end
end

function uu.isBirthDate(date)
	local year = tonumber(string.sub(date,1,4))
	local month = tonumber(string.sub(date,5,6))
	local day = tonumber(string.sub(date,7,8))
	if year < 1900 or year > 2100 or month >12 or month < 1 then
		return false
	end
	-- //月份天数表
	local month_days = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
	local bLeapYear = (year % 4 == 0 and year % 100 ~= 0) or (year % 400 == 0)
	if bLeapYear  then
		month_days[2] = 29;
	end

	if day > month_days[month] or day < 1 then
		return false
	end
	return true
end

function uu.isAllNumberOrWithXInEnd(str)
	local ret = string.match(str,"%d+X?")
	return ret == str
end

function  uu.checkSum(idcard)
	-- // wi =2(n-1)(mod 11) 
	local wi = { 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2, 1 }
	-- // verify digit 
	local vi= { "1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2" }
	local nums = {}
	local _idcard = string.sub(idcard,1,17)
	for ch in _idcard:gmatch"." do
		table.insert(nums,tonumber(ch))
	end
	local sum = 0
	for i,k in ipairs(nums) do
		sum = sum + k * wi[i]
	end
	return vi [sum % 11+1] == string.sub(idcard,18,18 )
end
--身份证验证
function uu.verifyIDCard(idcard)
	if string.len(idcard) ~= 18 then
		return false
	end

	if not uu.isAllNumberOrWithXInEnd(idcard) then
		return false
	end
	-- //第1-2位为省级行政区划代码，[11, 65] (第一位华北区1，东北区2，华东区3，中南区4，西南区5，西北区6)
	local nProvince = tonumber(string.sub(idcard,1, 2))
	if( nProvince < 11 or nProvince > 65 ) then
		return false
	end

	-- //第3-4为为地级行政区划代码，第5-6位为县级行政区划代码因为经常有调整，这块就不做校验
	-- //第7-10位为出生年份；//第11-12位为出生月份 //第13-14为出生日期
	if not uu.isBirthDate(string.sub(idcard,7,14)) then
		return false
	end

	if not uu.checkSum(idcard) then
		return false
	end

	return true
end

function uu.NumberSubComma(num)
	local strNum = tostring(num)
	local lenStr = string.len(strNum)
	local ret = ""
	for i = 1 , math.ceil(lenStr/3) do
		local startIdx = lenStr - 3 * i + 1
		local endIdx = lenStr - 3 * (i - 1)
		if startIdx < 1 then startIdx = 1 end
		if i == 1 then
			ret = string.sub(strNum,startIdx,endIdx) .. ret
		else
			ret = string.sub(strNum,startIdx,endIdx) .. "," .. ret
		end
	end
	return ret
end

---切换场景
function uu.ChangeScene(sceneName, callback, isAsync)
	--isAsync = isAsync or true
	--LuaFramework.SceneManager.ChangeScene(sceneName, isAsync, function ()
	--    if callback then
	--        callback()
	--    end
	--end)

	--if Scenes[sceneName] then
	--    for k,v in pairs(Scenes)do
	--        if k==sceneName then v:Show()
	--        else v:Hide()end
	--    end
	--    if callback then callback()end
	--else
	--    local obj = NewObject(SceneObjs[sceneName])
	--    obj.name = sceneName;
	--    if callback then callback()end
	--    for k,v in pairs(Scenes)do
	--        if k==sceneName then v:Show()
	--        else v:Hide()end
	--    end
	--end

	for v in top(Scenes)do
		Destroy(v.go)
		table.removeValue(Scenes,v)
	end
	local obj = NewObject(SceneObjs[sceneName])
	obj.name = sceneName
	if callback then callback()end
end

function uu.LoadImgSpriteFromAb(abName, path)
	local texture = resMgr.LoadAsset(abName, path)
	if texture then
		if string.find(tostring(texture), 'Sprite') then
			return texture
		else
			return Sprite.Create(texture, UnityEngine.Rect(0,0,texture.width,texture.height), Vector2(0.5,0.5))
		end
	end
end

function uu.LoadImgSprite(path)
	local texture = resMgr.LoadAsset("image", path)
	if texture then
		if string.find(tostring(texture), 'Sprite') then
			return texture
		else
			return Sprite.Create(texture, UnityEngine.Rect(0,0,texture.width,texture.height), Vector2(0.5,0.5))
		end
	end
end

--设置图集的image
function uu.LoadPackImgSprite(path)
	if LuaFramework.AppConst.UseResourcesLoad then
		return uu.LoadImgSprite(path)
	else
		return resMgr.LoadAsset("image", path)
	end
end

--查找对象--
function uu.findObject(str)
	local obj = GameObject.Find(str);
	return obj and obj.transform
end

function uu.destroyObject(obj)
	if obj and tostring(obj) ~= "null" then
		GameObject.Destroy(obj.gameObject or obj.transform.gameObject)
	end
end

function uu.NewObject(prefab)
	if prefab then
		return GameObject.Instantiate(prefab);
	end
end

function uu.resizeObjectWidth( obj, width )
	obj.sizeDelta = Vector2(width, obj.rect.height);
end

function uu.Md5Password( password )
	if password and password ~= "" and #password ~= 32 then
		return Util.Md5(Util.Base64(Util.Md5(string.lower(password))))
	end
	return password
end

function uu.GenerateKey(str)
	return Util.Md5(str.."E8FE168AD73Fqp*s$yGAME")
end

function uu.GenerateKey_lower(str)
	return Util.Md5(str..string.lower("E8FE168AD73Fqp*s$yGAME"))
end

function uu.GenerateKey_GB(str)
	return Util.Md5_GB(str.."E8FE168AD73Fqp*s$yGAME")
end

function uu.HttpGetEx(url, onResponse, onError, onFinish, times)
	if nil == url or "" == url then
		uu.SafeCallFunc(onError, "HttpGet Url is null")
		return nil,nil
	end

	local t = times or 20
	local www = WWW(url)

	local co  = nil
	local co2 = DelayRun(t, function()
		uu.CancelDelayRun(co)
	end)

	co = coroutine.start(function()
		coroutine.www(www)
		if not www.error then
			uu.SafeCallFunc(onResponse, www)
		else
			uu.SafeCallFunc(onError, www.error)
		end
		uu.SafeCallFunc(onFinish, www)
		uu.CancelDelayRun(co2)
	end)

	return www, co
end

function uu.HttpGet( url, onResponse, onError, onFinish )
	if nil == url or "" == url then
		uu.SafeCallFunc(onError, "HttpGet Url is null")
		return nil, nil
	end
	local www = WWW(url)
	local co = coroutine.start(function()
		coroutine.www(www)
		if not www.error then
			uu.SafeCallFunc(onResponse, www)
		else
			uu.SafeCallFunc(onError, www.error)
		end
		uu.SafeCallFunc(onFinish, www)
	end)
	return www, co
end

function uu.HttpPost(url, wwwForm, onResponse, onError, onFinish)
	if nil == url or "" == url then
		uu.SafeCallFunc(onError, "HttpGet Url is null")
		return nil, nil
	end
	local www = WWW(url, wwwForm)
	local co = coroutine.start(function()
		coroutine.www(www)
		if not www.error then
			uu.SafeCallFunc(onResponse, www)
		else
			uu.SafeCallFunc(onError, www.error)
		end
		uu.SafeCallFunc(onFinish, www)
	end)
	return www, co
end

function uu.HttpGetJson(url, onResponse, onError, onFinish)
	return uu.HttpGet(url, function(www)
		local data = Json.decode(www.text).result
		if data.value == "0" then
			uu.SafeCallFunc(onResponse, data.data, www)
		else
			uu.SafeCallFunc(onError, data.message, www)
		end
	end, onError, onFinish)
end

function uu.GetIsAbleHotUpdate(callback)
	local CC = require("CC")
	local urlHanlde = CC.UrlConfig.IPArea
	local key = "cjbRq8KBLScWPMVL"
	local sign = Util.Md5(key)
	local url = string.format(urlHanlde,sign,CC.Config.Info.GameId)
	log("查询IP域url：" .. url)
	uu.HttpGet(url,function(www)
		log("查询IP域返回:" .. tostring(www.text))
		local rsp = Json.decode(www.text)
		if rsp and rsp.result and rsp.result.data then
			local data = tostring(rsp.result.data)
			if string.find(data,"美国") then
				--只有当查询结果成功，并且包含“美国”二字才算才返回false
				callback(false)
			else
				callback(true)
			end
		else
			log("查询IP域有返回，但是没有数据,就当不是美国玩家吧，让进！")
			callback(true)
		end
	end,function(err)
		log("查询IP域失败,就当不是美国玩家吧，让进:" .. tostring(err))
		callback(true)
	end)
end

function uu.getComponent(obj, typeName)
	if not obj then
		uu.log("Can not getcomponent from null!!!")
		return nil
	end
	if obj:GetComponent(typeName) == nil then
		uu.log("component not find : " .. obj.name .. "-->" .. typeName)
		return nil
	end
	return obj:GetComponent(typeName)
end

function uu.setText(obj, str)
	local u_text = uu.getComponent(obj, "Text")
	if u_text then
		u_text.text = str
	end
end

-- image需要添加相应图片路径和名称
function uu.setImage(obj, image)
	local u_image = uu.getComponent(obj, "Image")
	if u_image then
		u_image.sprite = uu.LoadImgSprite(image)
	end
end

function uu.SetSprite(obj, name)
	local u_image = uu.getComponent(obj, "Image")
	if u_image then
		u_image.sprite = uu.LoadImgSpriteFromAb("atlas", name .. ".png")
	end
end

function uu.newGameObject(prefab)
	if prefab then
		return GameObject.Instantiate(prefab);
	end
end

function uu.UguiAddChild(parent, prefab, childName)
	if not prefab then
		uu.log("Can not add null prefab!!!")
		return
	end
	local newObj = uu.newGameObject(prefab)
	if parent then
		newObj.transform:SetParent(parent.transform, false)
	end
	if childName and type(childName) == "string" then
		newObj.name = childName
	end
	newObj:SetActive(true)
	return newObj
end

-- texture需要添加相应图片路径和名称
function uu.subSetImage( obj, childNode, texture )
	local img = uu.subGetObject(obj, childNode, "Image")
	img.sprite = uu.LoadImgSprite(texture)
end

function uu.subSetText( obj, childNode, str )
	local _text = uu.subGetObject(obj, childNode, "Text")
	_text.text = str
end

function uu.subGetObject( node, childNode, typeName )
	return node.transform:SubGet(childNode, typeName)
end

function uu.findGameObject( obj, childNode )
	return obj.transform:FindChild(childNode)
end

function uu.hideGameObject( obj, childNode )
	uu.findGameObject(obj, childNode):SetActive(false)
end

function uu.showGameObject( obj, childNode )
	uu.findGameObject(obj, childNode):SetActive(true)
end

function uu.destroyAllChilds( transform, flag )
	Util.ClearChild(transform, flag or false)
end

-- type:1为大厅，2位游戏内
function uu.panelShowAction(viewHandle, gPanel, type)
	local CC = require("CC")
	local distance = -800
	if type ~= 1 then
		distance = 800
	end

	viewHandle:RunAction(gPanel,  {"localMoveBy", distance, 0, 0.2, from=1, ease=CC.Action.EOutSine})
end

function uu.ReplaceFace(message, size)
	local CC = require("CC")
	local ret = ""
	local isz = size or 25
	local r_idx = string.find(message, ']')
	while r_idx do
		local len = string.len(message)
		local rec = string.sub(message, 1, r_idx)
		local l_idx = uu.StringLastFind(rec, '%[')

		if l_idx and (r_idx - l_idx <= CC.ChatConfig.CHAT_FACE_LENGHT + 1) then
			local front = (l_idx > 1) and (string.sub(message, 1, l_idx - 1)) or ""
			local name = string.sub(message, l_idx + 1, r_idx - 1)
			local temp = string.format("%s<size=%d>[%s]</size>", front, isz, name)
			ret = ret .. temp
		else
			ret = ret .. string.sub(message, 1, r_idx)
		end
		-- next
		local i = r_idx + 1
		if i < len then
			message = string.sub(message, i, len)
		else
			message = ""
		end
		r_idx = string.find(message, ']')
	end
	ret = ret .. message
	return ret
end

--是否平台场景
function uu.IsPlatfromScene()
	local name = LuaFramework.SceneManager.GetCurSceneName()
	if name == "main" or name == "root" or name == "main_GT" or name == "main_DJS" then
		return true
	end
	return false
end

function uu.UIAction(target)
	local CC = require("CC")
	local gameObject = target.transform.gameObject
	target:RunAction(target, {"scaleTo", 1, 1, 0.3, ease=CC.Action.EOutBack})
end

function uu.UIFadeOut(target)
	local gameObject = target.transform.gameObject
	target.transform = gameObject.transform

	target:RunAction(target, {"fadeToAll", 100, 0})
	target:RunAction(target, {"fadeToAll", 255, 0.2})
end

function uu.LoadPrefab(bundleName, prefabName, parent, name,useSelfLayer)
	return resMgr.LoadPrefab(bundleName, prefabName, parent, name,useSelfLayer)
end

local _playersIcon = nil
function uu.GetPartnerWeixinIcon(iconUrl, compCallback, failCallback)
	_playersIcon = _playersIcon or {}
	_playersIcon[iconUrl] = _playersIcon[iconUrl] or {}

	local icon  = _playersIcon[iconUrl]
	if icon.tex ~= nil then
		compCallback(icon.tex)
	else
		if icon.started then
			return
		end
		local www = uu.HttpGet(iconUrl, function(www)
			icon.started = true
			local tex = www.texture
			icon.tex = tex
			compCallback(tex)
		end, function(error)
			icon.started = false
			if failCallback then
				failCallback(error)
			end
		end)
		if www and not www.error then
			icon.started = true
		end
	end
end

function uu.SetWXImg(playerObj, imgUrl)
	uu.GetPartnerWeixinIcon(imgUrl, function(tex)
		playerObj:SetImage(tex)
	end)
end

function uu.SetWeixinImage(playerObj, imgName)
	-- local CC = require("CC")
	-- if CC.Player.weixin and CC.Player.weixin.headimgurl then
	--     if CC.ImageCache.Cache[CC.Player.weixin.headimgurl] then
	--         playerObj:SetImage(CC.ImageCache.Cache[CC.Player.weixin.headimgurl])
	--     else
	--         --用临时图片texture暂待微信头像纹理，以免微信头像长时间加载不出来
	--         CC.ImageCache.Cache[CC.Player.weixin.headimgurl] = resMgr.LoadAsset("image", "yxdt_tx1")
	--         uu.HttpGet(CC.Player.weixin.headimgurl, function(www)
	--             CC.ImageCache.Cache[CC.Player.weixin.headimgurl] = www.texture
	--             playerObj:SetImage(CC.ImageCache.Cache[CC.Player.weixin.headimgurl])
	--         end)
	--     end
	-- elseif imgName then
	--     uu.setImage(playerObj, imgName)
	-- else
	uu.setImage(playerObj, "yxdt_tx1")--默认
	-- end
end

function uu.getUserMac()
	local CC = require("CC")
	local usermac = "00:00:00:00:00:00"
	if CC.Platform.isIOS then
		local temp = Util.GetUUID()
		if temp ~= "" then
			usermac = temp
		end
	elseif CC.Platform.isAndroid then
		local iemi = Client.GetDeviceIEMI()
		if iemi == "" then
			local temp = Client.GetMACAddress()
			if temp ~= "" then
				usermac = temp
			end
		else
			usermac = iemi
		end
	end

	return usermac
end

--获取微信分享链接
function uu.WeiXinShareUrl()
	local CC = require("CC")
	return CC.MiscConfig.GetWeChatShareUrl()
end

--[[
    微信分享：
    iType:1分享好友，2分享朋友圈
    iTitle:标题
    text:内容
    imageName:分享显示的Icon名字
    url：分享关联的链接

    注：后3个参数不用填
]]
function uu.WeiXinShare(iType, iTitle, text, imageName, url,iPicquality)
	local CC = require("CC")
	iType = iType or 1
	iTitle = iTitle or "不能为空"
	text = text or "不能为空"
	imageName = imageName or "WxShareIcon"
	if imageName == "WxShareIcon" and CC.Config.ISGTPlatform() then
		imageName = "WxShareIcon_GT"
	end
	if imageName == "WxShareIcon" and CC.Config.ISZombie2Platform()  and CC.Platform.isIOS then
		imageName = "WxShareIcon_DJS"
	end
	url = url or uu.WeiXinShareUrl()
	iPicquality = iPicquality or 32
	WeiXinUtil.WeiXinShare(iType, iTitle, text, imageName, url,iPicquality)
end

--[[
    微信分享图片：
    iType:1分享好友，2分享朋友圈
    iTitle:标题
]]
function uu.WeixinSharePicture(iType,iTitle,imgName,iPicquality)
	iType = iType or 1
	iTitle = iTitle or "不能为空"
	imgName = imgName or "不能为空"
	iPicquality = iPicquality or 32
	WeiXinUtil.WeixinSharePicture(iType,iTitle,imgName,iPicquality)
end

--[[
    截屏分享:
    iType:1分享好友，2分享朋友圈
    iTitle:标题
]]
function uu.ShareGetCaptureScreen(iType,iTitle,iPicquality)
	iType = iType or 1
	iTitle = iTitle or "不能为空"
	iPicquality = iPicquality or 32
	WeiXinUtil.ShareGetCaptureScreen(iType,iTitle,iPicquality)
end

--给url加上时间戳，解决缓存问题
function uu.UrlWithTimeStamp(url)
	local CC = require("CC")
	--为了能再预发布测试环境下，能实时拿到最新的资源，需要加上时间戳，正式环境下不加，否则DNS失效，资源服可能会炸
	if CC.CommonConfig.GetIsOnlineDebug() or CC.CommonConfig.GetIsLocalDebug() then
		url = CC.UrlConfig.ReplaceDebugUrl(url)
		return url .. "?timestamp=" .. Util.GetTimeStamp(false)
	else
		return url
	end
end

--从一个路径中窃取文件名，例如 xx/xx/xx/a.apk,执行将得到a.apk
function uu.CutFileNameFromPath(path)
	return string.gsub(path, "(.*/)", "")
end

--求x字节的大小，超过1024B显示KB，超过1M显示MB
function uu.GetByteSizeString(byteSize)
	local sizestring = ""
	if byteSize>1024 and byteSize<=1048576 then
		sizestring=Mathf.Round(byteSize/1024).."KB"
	elseif byteSize>1048576 then
		sizestring=Mathf.Round(byteSize/1048576).."MB"
	else
		sizestring=byteSize.."B"
	end
	return sizestring
end


--------------------------------------------
-----dump 打印结构
-- value[all type ??] 要打印的值
-- desciption 描述
-- nesting[int]  深度 默认为3
--------------------------------------------
function uu.Dump(value, desciption, nesting,str_begin)
	if type(nesting) ~= "number" then nesting = 3 end

	local lookupTable = {}
	local result = {}

	local function _v(v)
		if type(v) == "string" then
			v = "\"" .. v .. "\""
		end
		return tostring(v)
	end

	--local traceback = string.split(debug.traceback("", 2), "\n")
	--rint("dump from: " .. string.trim(traceback[3]))

	local function _dump(value, desciption, indent, nest, keylen)
		--协议结构处理
		local fields = type(value) == "table" and value._fields or nil
		if fields then
			value = table.copy(value)
			for k,v in pairs(fields) do
				if type(v) == "table" then
					v = table.copy(v)
					v._listener = nil
					v._type_checker = nil
					v._message_descriptor = nil
				end
				value[k.name] = v
			end
			--屏蔽字段
			value._fields = nil
			value._cached_byte_size = nil
			value._cached_byte_size_dirty = nil
			value._is_present_in_parent = nil
			value._listener = nil
			value._listener_for_children = nil
			value._message_descriptor = nil
		end

		desciption = desciption or "<var>"
		local spc = ""
		if type(keylen) == "number" then
			spc = string.rep(" ", keylen - string.len(_v(desciption)))
		end
		if type(value) ~= "table" then
			result[#result +1 ] = string.format("%s%s%s = %s", indent, _v(desciption), spc, _v(value))
		elseif lookupTable[value] then
			result[#result +1 ] = string.format("%s%s%s = *REF*", indent, desciption, spc)
		else
			lookupTable[value] = true
			if nest > nesting then
				result[#result +1 ] = string.format("%s%s = *MAX NESTING*", indent, desciption)
			else
				result[#result +1 ] = string.format("%s%s = {", indent, _v(desciption))
				local indent2 = indent.."    "
				local keys = {}
				local keylen = 0
				local values = {}
				for k, v in pairs(value) do
					keys[#keys + 1] = k
					local vk = _v(k)
					local vkl = string.len(vk)
					if vkl > keylen then keylen = vkl end
					values[k] = v
				end
				table.sort(keys, function(a, b)
					if type(a) == "number" and type(b) == "number" then
						return a < b
					else
						return tostring(a) < tostring(b)
					end
				end)
				for i, k in ipairs(keys) do
					_dump(values[k], k, indent2, nest + 1, keylen)
				end
				result[#result +1] = string.format("%s}", indent)
			end
		end
	end
	_dump(value, desciption, str_begin or " ", 1)
	local str_res = ""
	for i, line in ipairs(result) do
		str_res = str_res ..line.."\n"
	end

	return str_res
end

function uu.HasGameInstall( appPackage )
	return Client.CheckHasInstallAPK(appPackage) ~= 0
end

function uu.HasGameFile( filePath )
	return Util.HasFile(filePath)
end

--nNum保留n位小数,返回字符串
function uu.GetPreciseDecimal(nNum, n)
	if type(nNum) ~= "number" then
		return nNum;
	end

	n = n or 0;
	n = math.floor(n)
	local fmt = '%.' .. n .. 'f'
	local nRet = string.format(fmt, nNum)
	return nRet;
end

--检查url字符串中的不合法字符，如果有则返回非合法字符，如果没有，则返回nil
function uu.CheckUnLegalUrlStr(str)
	local unlegalStrs =
	{
		"<",
		"> ",
		"%.%.", --%为转义符，%.%.表示..
		"{",
		"}"
	}
	for _,v in ipairs(unlegalStrs) do
		if string.find(str,v) then
			if v == "%.%." then
				return ".."
			else
				return v
			end
		end
	end
	return nil
end

local _UnityLogViewNode = nil
function uu.OpenLogView()
	if _UnityLogViewNode then
		_UnityLogViewNode.transform:Show()
	else
		resMgr.LoadAssets("prefab", {"UnityLogViewer"}, function(pref)
			local pref = pref[0]
			_UnityLogViewNode = uu.UguiAddChild(nil, pref,"[UnityLogViewer]")
		end)
	end
end

function uu.CloseLogView()
	if _UnityLogViewNode then
		_UnityLogViewNode.transform:Hide()
	end
end

function uu.FilteSpecChars(s)
	local ss = {}
	local k = 1
	while true do
		if k > #s then break end
		local c = string.byte(s,k)
		if not c then break end
		if c<192 then
			if (c>=48 and c<=57) or (c>= 65 and c<=90) or (c>=97 and c<=122) then
				table.insert(ss, string.char(c))
			end
			k = k + 1
		elseif c<224 then
			k = k + 2
		elseif c<240 then
			if c>=228 and c<=233 then
				local c1 = string.byte(s,k+1)
				local c2 = string.byte(s,k+2)
				if c1 and c2 then
					local a1,a2,a3,a4 = 128,191,128,191
					if c == 228 then a1 = 184
					elseif c == 233 then a2,a4 = 190,c1 ~= 190 and 191 or 165
					end
					if c1>=a1 and c1<=a2 and c2>=a3 and c2<=a4 then
						table.insert(ss, string.char(c,c1,c2))
					end
				end
			end
			k = k + 3
		elseif c<248 then
			k = k + 4
		elseif c<252 then
			k = k + 5
		elseif c<254 then
			k = k + 6
		end
	end
	return table.concat(ss)
end

function uu.OpenURL(url)
	local CC = require("CC")
	if CC.Platform.isAndroid then
		Application.OpenURL(url)
	else
		Application.OpenURL(url)
		Util.PlayerRequestOrderid(url)
	end
end

-- 转换到本地时间
function uu.GetLocalTimeWithString(timeStr)
	local now = os.time()
	local dif =  os.difftime(now, os.time(os.date("!*t", now)))
	local time = os.date("*t", uu.GetTimeStamp(timeStr) + dif);
	local date = os.date("%Y-%m-%d %H:%M:%S", os.time(time));
	return date;
end

-- 转换到本地时间
function uu.GetLocalTimeWithTab(timeStr)
	local now = os.time()
	local dif =  os.difftime(now, os.time(os.date("!*t", now)))
	local date = os.date("*t", uu.GetTimeStamp(timeStr) + dif);
	return date;
end

-- 时间转时间戳 时间格式:2019-12-24 15:53:23
function uu.GetTimeStamp(timeStr)
	if type(timeStr) ~= "string" then
		return 0
	end

	local fun = string.gmatch(timeStr, "%d+")
	local y = fun() or 0
	if y == 0 then log("year == 0") return 0 end
	local m = fun() or 0
	if m == 0 then log("month == 0") return 0 end
	local d = fun() or 0
	if d == 0 then log("day == 0") return 0 end
	local H = fun() or 0
	if H == 0 then log("hour == 0") return 0 end
	local M = fun() or 0
	if M == 0 then log("minute == 0") return 0 end
	local S = fun() or 0
	if S == 0 then log("second == 0") return 0 end

	local timeStamp = os.time( { year = y, month = m, day = d, hour = H, min = M, sec = S })
	if not timeStamp then
		return 0
	else
		return timeStamp < 0 and 0 or timeStamp
	end
end

-- 自定义时间格式
function uu.GetTime(timeStamp, year, month, day, hour, minute, second)
	if not timeStamp then
		return ""
	end

	local str = ""
	if year and year ~= "" then
		str = str .. os.date("%Y" .. year, timeStamp)
	end

	if month and month ~= "" then
		str = str .. os.date("%m" .. month, timeStamp)
	end

	if month and month ~= "" then
		str = str .. os.date("%d" .. day, timeStamp)
	end

	if hour and hour ~= "" then
		str = str .. os.date("%H" .. hour, timeStamp)
	end

	if minute and minute ~= "" then
		str = str .. os.date("%M" .. minute, timeStamp)
	end

	if second and second ~= "" then
		str = str .. os.date("%S" .. second, timeStamp)
	end

	return str
end

-- 获取Table长度
function uu.GetTableLength(table)
	local size = 0
	if table == nil then
		return size
	end

	for _, v in pairs(table) do
		size = size + 1
	end

	return size
end

-- Table深拷贝
function uu.DeepCopy(object)
	local lookupTable = {}
	local function _copy(objectT)
		if type(objectT) ~= "table" then
			return objectT
		elseif lookupTable[objectT] then
			return lookupTable[objectT]
		end

		local newTable = {}
		lookupTable[objectT] = newTable
		for index, value in pairs(objectT) do
			newTable[_copy(index)] = _copy(value)
		end

		return setmetatable(newTable, getmetatable(objectT))
	end

	return _copy(object)
end

function uu.ExchangeValue(v1,v2)
	local v = v1
	v1 = v2
	v2 = v
	return v1,v2
end

return uu